#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;

class segment_tree {
	vector<double> arr;
	vector<double> asum;
	vector<double> ssum;
	vector<double> ladd;

	void lazy(int i, double v, int n)
	{
		ssum[i] += 2 * v * asum[i] + n * v * v;
		asum[i] += v * n;
		ladd[i] += v;
	}

	void up(int i)
	{
		asum[i] = asum[i << 1] + asum[i << 1 | 1];
		ssum[i] = ssum[i << 1] + ssum[i << 1 | 1];
	}

	void down(int i, int ln, int rn)
	{
		if (ladd[i]) {
			lazy(i << 1, ladd[i], ln);
			lazy(i << 1 | 1, ladd[i], rn);
			ladd[i] = 0;
		}
	}

	void build(int l, int r, int i)
	{
		if (l == r) {
			asum[i] = arr[l];
			ssum[i] = arr[l] * arr[l];
		} else {
			int mid = (l + r) >> 1;
			build(l, mid, i << 1);
			build(mid + 1, r, i << 1 | 1);
			up(i);
		}
	}

    public:
	segment_tree(int n, vector<double> &arr) : arr(arr), asum(n << 2, 0), ssum(n << 2, 0), ladd(n << 2, 0)
	{
		build(1, n, 1);
	}

	void update(int jobl, int jobr, double v, int l, int r, int i)
	{
		if (jobl <= l && r <= jobr) {
			lazy(i, v, r - l + 1);
		} else {
			int mid = (l + r) >> 1;
			down(i, mid - l + 1, r - mid);
			if (jobl <= mid) {
				update(jobl, jobr, v, l, mid, i << 1);
			}
			if (mid < jobr) {
				update(jobl, jobr, v, mid + 1, r, i << 1 | 1);
			}
			up(i);
		}
	}

	pair<double, double> query(int jobl, int jobr, int l, int r, int i)
	{
		if (jobl <= l && r <= jobr) {
			return { asum[i], ssum[i] };
		}
		int mid = (l + r) >> 1;
		down(i, mid - l + 1, r - mid);
		pair<double, double> ans1(0, 0), ans2(0, 0);
		if (jobl <= mid) {
			ans1 = query(jobl, jobr, l, mid, i << 1);
		}
		if (mid < jobr) {
			ans2 = query(jobl, jobr, mid + 1, r, i << 1 | 1);
		}
		return { ans1.first + ans2.first, ans1.second + ans2.second };
	}
};

int main()
{
	cout << setprecision(4) << setiosflags(ios::fixed);
	int n = 0, m = 0;
	cin >> n >> m;
	vector<double> arr(n + 1, 0);
	for (int i = 1; i <= n; i++) {
		cin >> arr[i];
	}

	segment_tree sgt(n, arr);
	pair<double, double> ans;
	double k;
	for (int i = 0, op, x, y; i < m; i++) {
		cin >> op;
		if (op == 1) {
			cin >> x >> y >> k;
			sgt.update(x, y, k, 1, n, 1);
		} else {
			cin >> x >> y;
			ans = sgt.query(x, y, 1, n, 1);
                        
                        int size = y - x + 1;
			double agv = ans.first / size;
			double ssum = ans.second / size - agv * agv;
			if (op == 2) {
				cout << agv << '\n';
			} else {
				cout << ssum << '\n';
			}
		}
	}

	return 0;
}